package com.woniuxy.Controller;

import com.woniuxy.entity.RbacManager;
import com.woniuxy.entity.ResponseEntity;
import com.woniuxy.exception.UnauthorizedException;
import com.woniuxy.service.impl.UserService;
import com.woniuxy.utils.JWTUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.concurrent.TimeUnit;

/**
 * @author: mayuhang  <br/>
 * Date: 2021/4/22:23:52  <br/>
 * Description:
 */
@RestController
public class UserController {
    @Autowired
    UserService userService;
    @Autowired
    RedisTemplate redisTemplate;
    @RequestMapping("/login")
    public ResponseEntity login(@RequestParam("username") String username,
                                @RequestParam("password") String password) {
//        //把传入的密码, 进行同样的加密处理  才能和数据库取出的密码比较
        SimpleHash simpleHash = new SimpleHash("MD5",password,username);
//        //获取加密后的 密码  同学们   还是要敲一下代码啊
//        核心代码 redistemplate在项目中 部分地方 尝试使用一下 ok
        String newPassword = simpleHash.toHex();
        //去数据库查出密码  可以下次直接通过token去数据库获取对象
        RbacManager user = userService.getUser(username);
        if(user.getPassword().equals(newPassword)){
            //生成token
            String sign = JWTUtil.sign(username, newPassword);
            //往redis中存一份 同时设置一个过期时间
            user.setToken(sign);
            redisTemplate.opsForValue().set(user.getToken(),user);
            //对某个key设置其过期时间  6000s后过期 但是请取消5分钟过期的jwt判断
            redisTemplate.expire(user.getToken(),6000, TimeUnit.SECONDS);
            System.out.println(redisTemplate.opsForValue().get(user.getToken()));
            return new ResponseEntity(200,"登录成功!",user);
        }
        return new ResponseEntity(200,"账号或密码错误!",null);
    }
    /**
     * Description : 不携带token直接请求的话 就是游客咯  <br/>
     * ChangeLog : 1. 创建 (2021/5/3 22:15 [mayuhang]);
     *
     * @return com.woniuxy.entity.ResponseEntity
     **/
    @GetMapping("/article")
    public ResponseEntity article() {
        Subject subject = SecurityUtils.getSubject();
        if (subject.isAuthenticated()) {
            return new ResponseEntity(200, "您已经登录", null);
        } else {
            return new ResponseEntity(200, "You are guest", null);
        }
    }
    /**
     * Description : 加注解 判断是否认证过的, 等同于之前的subject.isAuthenticated()  <br/>
     * ChangeLog : 1. 创建 (2021/5/3 22:51 [mayuhang]);
     *
     * @return com.woniuxy.entity.ResponseEntity
     **/
    @GetMapping("/require_auth")
    @RequiresAuthentication
    public ResponseEntity requireAuth() {
        return new ResponseEntity(200, "恭喜您登录成功,可以获取菜单数据了!", null);
    }
    /**
     * Description : 是否有某个角色, 等同于subject.hasRole,有多个的话 参考下面权限判断  <br/>
     * ChangeLog : 1. 创建 (2021/5/3 22:53 [mayuhang]);
     *
     * @return com.woniuxy.entity.ResponseEntity
     **/
    @GetMapping("/require_role")
    @RequiresRoles(value = {"1"})
    public ResponseEntity requireRole() {
        return new ResponseEntity(200, "你有超级管理员角色", null);
    }
    /**
     * Description : 是否有某个权限, 等同于subject.isPermitted  <br/>
     * ChangeLog : 1. 创建 (2021/5/3 22:53 [mayuhang]);
     *
     * @return com.woniuxy.entity.ResponseEntity
     **/
    @GetMapping("/require_permission")
    @RequiresPermissions(logical = Logical.AND, value = {"role:view", "perm_manage"})
    public ResponseEntity requirePermission() {
        return new ResponseEntity(200, "您正在访问权限，需要编辑，perm_manage权限的接口", null);
    }
    /**
     * Description : 所有401等权限认证, 错误的, 都到这里来~  <br/>
     * ChangeLog : 1. 创建 (2021/5/3 22:54 [mayuhang]);
     *
     * @return com.woniuxy.entity.ResponseEntity
     **/
    @RequestMapping(path = "/401")
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public ResponseEntity unauthorized() {
        return new ResponseEntity(401, "未经授权", null);
    }
}
